package com.yx.cloud.map.layer;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;

import com.aaa.lib.map.MapUtils;
import com.aaa.lib.map.MapView;
import com.aaa.lib.map.area.RectangleArea;
import com.iot.product.sweeper.bean.CleanAreaInfo;
import com.iot.product.sweeper.bean.CleanParam;
import com.iot.product.sweeper.bean.MapInfo;
import com.yx.cloud.R;
import com.yx.cloud.map.YXMapView;
import com.iot.product.sweeper.bean.AreaInfo;
import com.iot.common.utils.LogUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class YXCleanAreaLayer extends YXAreaLayer<RectangleArea> {
    private static final String TAG = "YXCleanAreaLayer";

    private static final int STOKEN_W = 4;
    private static final int STOKEN_MARGIN = 32;
    public static boolean isCleanAreaEditable = false;
    protected Paint orderBgPaint;
    /**
     * 缩放
     *
     * @param x 右下角拉伸到
     * @param y
     */
    float lastW, lastH;
    private Paint mPaint;       //画笔
    private Paint mTextPaint;       //画笔
    private Path mRectBorder;

    private DashPathEffect mDashPath;

    private Bitmap deleteIcon;  //左上角删除按钮
    private Bitmap rotateIcon;  //右上角的旋转按钮
    private Bitmap scaleIcon;   //右下角的缩放按钮

    private int borderColor;
    private int bgColor;
    private int textColor;


    private Matrix tempMatrix; //当前矩形 相对view的变换，偏移/缩放/旋转
    private float lastPosX;
    private float lastPosY;         //用于计算平移
    private float lastRtAngle;      //圆心->右上角 与x轴夹角  用于计算旋转
    private float areaWidth;
    private float areaHeight;

    public YXCleanAreaLayer(MapView mapView) {
        super(mapView);
        Resources resources = mapView.getResources();
        borderColor = resources.getColor(R.color.area_stroke);
        bgColor = resources.getColor(R.color.area_fill);
        textColor = resources.getColor(R.color.gray_666);
        deleteIcon = BitmapFactory.decodeResource(mapView.getContext().getResources(), R.mipmap.area_delete);
        rotateIcon = BitmapFactory.decodeResource(mapView.getContext().getResources(), R.mipmap.area_rotate);
        scaleIcon = BitmapFactory.decodeResource(mapView.getContext().getResources(), R.mipmap.area_drag);

        area = new RectangleArea();
        areaInfo = new CleanAreaInfo();

        tempMatrix = new Matrix();

        mRectBorder = new Path();
        mPaint = new Paint();
        mPaint.setStrokeWidth(5);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setAntiAlias(true);

        orderBgPaint = new Paint();
        orderBgPaint.setStyle(Paint.Style.FILL);
        orderBgPaint.setColor(Color.WHITE);
        orderBgPaint.setAntiAlias(true);

        mTextPaint = new Paint();
        mTextPaint.setColor(textColor);
        mTextPaint.setStyle(Paint.Style.FILL);
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
        mTextPaint.setTextSize(12 * resources.getDisplayMetrics().density);

        mDashPath = new DashPathEffect(new float[]{15, 5}, 0);

    }

    @Override
    public void draw(Canvas canvas) {
        if (!visible) {
            return;
        }
        //        drawWithMatrix(canvas);
        drawWithMatrixValue(canvas);
    }

    public void drawWithMatrix(Canvas canvas) {
        canvas.save();

        canvas.setMatrix(mMapView.getTransform());
        drawRect(canvas);
        drawAreaText(canvas);

        //在可编辑状态 并且获取到焦点
        if (isEditable() && focusId == areaInfo.getId()) {
            drawIcon(canvas);
        }
        canvas.restore();
    }

    public void drawWithMatrixValue(Canvas canvas) {
        float scale = ((YXMapView)mMapView).getScale();

        canvas.save();
        canvas.setMatrix(mMapView.getTransform());
        drawRect1(canvas, scale);
        canvas.restore();


        drawAreaText1(canvas, scale);
        if (isEditable() && focusId == areaInfo.getId()) {
            drawIcon1(canvas, scale);
        }
    }


    @Override
    protected boolean onTouchDown(float x, float y) {
        lastPosX = x;
        lastPosY = y;

        float scale = ((YXMapView)mMapView).getScale();
        //判断点击位置
        if (MapUtils.isPointInCircle(x, y, area.lt, deleteIcon.getWidth() / scale)) {
            operate = OP_DELETE;
            return true;
        } else if ((((YXMapView) mMapView).canRotateCleanArea) && MapUtils.isPointInCircle(x, y, area.rt, rotateIcon.getWidth() / scale)) {
            operate = OP_ROTATE;
            //开始旋转时 设置右上角到圆心的初始角度
            lastRtAngle = MapUtils.getRotateByRect(x, y, area.center.x, area.center.y);
            return true;
        } else if (MapUtils.isPointInCircle(x, y, area.rb, scaleIcon.getWidth() / scale)) {
            operate = OP_SCALE;
            return true;
        } else if (MapUtils.isPointInRectangle(area.lt.x, area.lt.y, area.rt.x, area.rt.y, area.rb.x, area.rb.y, area.lb.x, area.lb.y, x, y)) {
            operate = OP_MOVE;
            return true;
        } else {
            //不在点击范围内 下一位
            operate = OP_NONE;
            return false;
        }
    }

    @Override
    protected boolean onTouchMove(float x, float y) {
        LogUtils.i("move to x: " + x + " y : " + y);
        if (operate == OP_MOVE) {
            move(x, y);
            return true;
        }else if (operate == OP_ROTATE) {
            rotate(x, y);
            return true;
        } else if (operate == OP_SCALE) {
            scale(x, y);
            return true;
        }  else if (operate == OP_DELETE) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    protected boolean onTouchUp(float x, float y) {
        //判断点击位置
        if (operate == OP_DELETE) {
            delete();
            return true;
        }
        return false;
    }

    /**
     * 删除
     */
    private void delete() {
        mMapView.getLayerManager().removeLayer(this);
    }

    /**
     * 缩放是通过计算右下角的距离实现
     * 如超过最大返回 将做同比缩放
     *
     * @param x
     * @param y
     */
    private void scale(float x, float y) {
        //把触摸点 通过图层本身旋转矩阵 反转回正交坐标
        tempMatrix.setRotate(area.rotate,area.lt.x,area.lt.y);
        MapUtils.getInverseRotatedPoint(tempMatrix, x, y,tmpPoint);

        //此时 宽度 高度就是 它与左上角的差值
        float w=tmpPoint[0]-area.lt.x;
        float h=tmpPoint[1]-area.lt.y;

        MapInfo map = ((YXMapView) mMapView).getMap().getMap();
        float realW = map.getActualSize(w);
        float realH = map.getActualSize(h);

        //矩形实际长宽小于0.5 设置为0.5
        if (realW < ((YXMapView) mMapView).getMinCleanAreaSize()) {
            w = map.getScreenSize(((YXMapView) mMapView).getMinCleanAreaSize());
        }
        if (realH <  ((YXMapView) mMapView).getMinCleanAreaSize()) {
            h = map.getScreenSize(((YXMapView) mMapView).getMinCleanAreaSize());
        }

        //实际大小不能超过500
        if (realH * realW > MAX_AREA_SIZE) {
            //如果超过大小 就计算触摸点与左上角的连线  再将其缩小到MAX_AREA_SIZE长度  分别对宽高做缩放就能得到当前的w和h
            float scale = (float) Math.sqrt(MAX_AREA_SIZE / (realH * realW));
            w = map.getScreenSize(realW * scale);
            h = map.getScreenSize(realH * scale);
        }

        //矩形长宽不能小于两个图标的距离
//        mMapView.getTransform().getValues(tempMatrixValue);
//        float scale = tempMatrixValue[0];
//        if (h < 2 * deleteIcon.getWidth() / scale) {
//            //矩形太小 不操作
//            h = 2 * deleteIcon.getWidth() / scale;
//        }
//
//        if (w < 2 * deleteIcon.getWidth() / scale) {
//            w = 2 * deleteIcon.getWidth() / scale;
//        }

        // 这里通过右下角来设置中心点 ，限制不完善， 缩放到最小后 会把控件推走。。。。 不过这个很好玩 所以没删
        //        area.getCenter().x = (area.lt.x + x) / 2;
        //        area.getCenter().y = (area.lt.y + y) / 2;


        //计算中心点  现在知道旋转角度 ， 以及高宽

        //求出对角钱长度一半
        //中心点X=左上角X+ 半对角线长  中心点Y= 左上角Y+0
        float centerX = area.lt.x + (float) Math.sqrt(w * w + h * h) / 2;
        float centerY = area.lt.y;
        // 算出当前对角线与lt rt连线的夹角   加上当前矩形的旋转角度就得到当前对角线的角度
        float degree = (float) (180 * Math.atan2(h, w) / Math.PI);
        tempMatrix.setRotate(area.rotate + degree, area.lt.x, area.lt.y);
        //从0度旋转到当前角度  获取到中心点
        MapUtils.getTransformedPoint(tempMatrix, centerX, centerY, area.center);

        area.setRect(area.center, w, h, area.rotate);
        lastRtAngle = MapUtils.getRotateByRect(area.rt.x, area.rt.y, area.center.x, area.center.y);
        LogUtils.i("cleanarea: scale " + area.toString());

        areaWidth = map.getActualSize(area.width);
        areaHeight = map.getActualSize(area.height);
        areaSize = areaWidth * areaHeight;

        mMapView.refresh();
    }


    /**
     * 平移
     *
     * @param x
     * @param y
     */
    private void move(float x, float y) {
        //计算平移距离
        float translateX = x - lastPosX;
        float translateY = y - lastPosY;

        //移动中心点 重新设置矩形
        area.setCenter(area.center.x + translateX, area.center.y + translateY);

        //记录上次触摸点
        lastPosX = x;
        lastPosY = y;

        mMapView.refresh();
    }

    /**
     * 旋转
     *
     * @param x
     * @param y
     */
    private void rotate(float x, float y) {

        //获取旋转后 右上角到圆心的角度
        float rtAngle = MapUtils.getRotateByRect(x, y, area.center.x, area.center.y);
        //当前旋转角度等于  之前的角度 加上增量
        float tempRotate = area.rotate + rtAngle - lastRtAngle;

        area.setRotate(tempRotate);
        lastRtAngle = MapUtils.getRotateByRect(area.rt.x, area.rt.y, area.center.x, area.center.y);

        mMapView.refresh();
    }

    public void initAreaLayer() {
        MapInfo map = ((YXMapView) mMapView).getMap().getMap();
        float minSize = map.getScreenSize(0.5f);
        float defaultSize = Math.max(map.width / 3f, minSize);

        area.setRect(map.width / 2f, map.height / 2f, defaultSize, defaultSize, 0);
        CleanAreaInfo areaInfo = new CleanAreaInfo();
        areaInfo.setType(YXAreaLayer.TYPE_CLEAN_AREA);
        areaInfo.setId(((YXMapView) mMapView).getUniqueAreaId(YXAreaLayer.TYPE_CLEAN_AREA));
        areaInfo.setStamp(new Date().getTime());
        areaInfo.setName("cleanarea-" + areaInfo.getId());
        this.areaInfo = areaInfo;

        areaWidth = map.getActualSize(area.width);
        areaHeight = map.getActualSize(area.height);
        areaSize = areaWidth * areaHeight;
    }

    @Override
    public void initAreaLayer(AreaInfo areaInfo) {
        List<Double> areaVetexs = areaInfo.getBorder();
        area.lt.x = (float) (double) areaVetexs.get(0);
        area.lt.y = (float) (double) areaVetexs.get(1);
        area.rt.x = (float) (double) areaVetexs.get(2);
        area.rt.y = (float) (double) areaVetexs.get(3);
        area.rb.x = (float) (double) areaVetexs.get(4);
        area.rb.y = (float) (double) areaVetexs.get(5);
        area.lb.x = (float) (double) areaVetexs.get(6);
        area.lb.y = (float) (double) areaVetexs.get(7);
        area.setRect(area.lt, area.rt, area.rb, area.lb);

        setAreaInfo(areaInfo);
        LogUtils.i("set layer area : " + area.toString());

        MapInfo map = ((YXMapView) mMapView).getMap().getMap();
        areaWidth = map.getActualSize(area.width);
        areaHeight = map.getActualSize(area.height);
        areaSize = areaWidth * areaHeight;
    }

    public void setCleanParam(CleanParam cleanParam) {
        CleanAreaInfo cleanAreaInfo = (CleanAreaInfo) areaInfo;
        cleanAreaInfo.setCleanTimes(cleanParam.cleanTimes);
        cleanAreaInfo.setSuction(cleanParam.suction);
        cleanAreaInfo.setHumidity(cleanParam.humidity);
        cleanAreaInfo.setSweepType(cleanParam.cleanType);
    }

    @Override
    public CleanAreaInfo getAreaInfo() {
        ArrayList<Double> points = new ArrayList<>();
        points.add((double) area.lt.x);
        points.add((double) area.lt.y);
        points.add((double) area.rt.x);
        points.add((double) area.rt.y);
        points.add((double) area.rb.x);
        points.add((double) area.rb.y);
        points.add((double) area.lb.x);
        points.add((double) area.lb.y);
        areaInfo.setBorder(points);
        return (CleanAreaInfo) areaInfo;
    }

    private void setBorder(RectangleArea area) {
        mRectBorder.reset();
        mRectBorder.moveTo(area.lt.x, area.lt.y);
        mRectBorder.lineTo(area.rt.x, area.rt.y);
        mRectBorder.lineTo(area.rb.x, area.rb.y);
        mRectBorder.lineTo(area.lb.x, area.lb.y);
        mRectBorder.close();
    }

    /**
     * 绘制矩形边框和内部的栅格线
     *
     * @param canvas
     */
    private void drawRect(Canvas canvas) {
        setBorder(area);

        //画边框
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(borderColor);
        mPaint.setPathEffect(mDashPath);
        canvas.drawPath(mRectBorder, mPaint);

        //画背景
        mPaint.setColor(bgColor);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setPathEffect(null); //清除虚线效果
        canvas.drawPath(mRectBorder, mPaint);


    }

    /**
     * 绘制删除 旋转 缩放按钮
     * 这种方式根据地图缩放图标
     *
     * @param canvas
     */
    private void drawIcon(Canvas canvas) {
        canvas.drawBitmap(deleteIcon, area.lt.x - deleteIcon.getWidth() / 2, area.lt.y - deleteIcon.getHeight() / 2, null);

        canvas.drawBitmap(rotateIcon, area.rt.x - rotateIcon.getWidth() / 2, area.rt.y - rotateIcon.getHeight() / 2, null);

        canvas.drawBitmap(scaleIcon, area.rb.x - scaleIcon.getWidth() / 2, area.rb.y - scaleIcon.getHeight() / 2, null);
    }
    //    这种方式不缩放图标
    //    private void drawIcon(Canvas canvas) {
    //        float offsetW = deleteIcon.getWidth() / 2;
    //        float offsetH = deleteIcon.getHeight() / 2;
    //
    //        tmpPoint.set(area.lt.x, area.lt.y);
    //        MapUtils.getTransformedPoint(mMapView.getTransform(), tmpPoint);
    //        canvas.drawBitmap(deleteIcon, tmpPoint.x-offsetW, tmpPoint.y-offsetH, null);
    //
    //        tmpPoint.set(area.rt.x , area.rt.y );
    //        MapUtils.getTransformedPoint(mMapView.getTransform(), tmpPoint);
    //        canvas.drawBitmap(rotateIcon, tmpPoint.x-offsetW, tmpPoint.y-offsetH, null);
    //
    //
    //        tmpPoint.set(area.rb.x, area.rb.y );
    //        MapUtils.getTransformedPoint(mMapView.getTransform(), tmpPoint);
    //        canvas.drawBitmap(scaleIcon, tmpPoint.x-offsetW, tmpPoint.y-offsetH, null);
    //    }

    private void drawRect1(Canvas canvas, float scale) {
        mPaint.setStrokeWidth(5 / scale);
        setBorder(area);

        //画边框
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(borderColor);
        mPaint.setPathEffect(new DashPathEffect(new float[]{15 / scale, 8 / scale}, 0));
        canvas.drawPath(mRectBorder, mPaint);

        //画背景
        mPaint.setColor(bgColor);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setPathEffect(null); //清除虚线效果
        canvas.drawPath(mRectBorder, mPaint);
    }

    private void drawAreaText(Canvas canvas) {

        canvas.rotate(area.rotate, area.center.x, area.center.y);
        mTextPaint.setTextSize(12);


        if (isEditable() && focusId == areaInfo.getId()) {
            canvas.drawCircle(area.center.x, area.center.y - mTextPaint.getTextSize(), mTextPaint.getTextSize() / 2 + 1, orderBgPaint);
            canvas.drawText((order + 1) + "", area.center.x, area.center.y - mTextPaint.getTextSize() * 2 / 3, mTextPaint);   //编号程序里从0开始 显示从1开始
            canvas.drawText(String.format("%.1f", areaWidth) + "*" + String.format("%.1f", areaHeight) + "m", area.center.x, area.center.y + mTextPaint.getTextSize() * 2 / 3, mTextPaint);
        } else {
            canvas.drawCircle(area.center.x, area.center.y, mTextPaint.getTextSize() / 2 + 1, orderBgPaint);
            canvas.drawText((order + 1) + "", area.center.x, area.center.y + mTextPaint.getTextSize() * 1 / 3, mTextPaint);   //编号程序里从0开始 显示从1开始
        }

        canvas.rotate(-area.rotate, area.center.x, area.center.y);
    }


    private void drawAreaText1(Canvas canvas, float scale) {
        //重新设置矩形 和文本宽高
        Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
        float textWidth = mTextPaint.measureText((order + 1) + "");   //测量文本长度
        float textHeight = fontMetrics.descent - fontMetrics.ascent;    //计算文本高度
        float radius = Math.max(textWidth, textHeight);

        getTransformedPoint(mMapView.getTransform(), area.center.x, area.center.y);
        canvas.rotate(area.rotate, tmpPoint[0], tmpPoint[1]);
        if (isEditable() && focusId == areaInfo.getId()) {
            //序号往上移 -textHeight/4   绘制文字时原本+ 1/3 height 是因为绘制基线
            canvas.drawCircle(tmpPoint[0], tmpPoint[1] - radius / 2 - textHeight / 4, radius / 2 + 5, orderBgPaint);
            canvas.drawText((order + 1) + "", tmpPoint[0], tmpPoint[1] - radius / 2 - textHeight / 4 + textHeight / 3, mTextPaint);            //编号程序里从0开始 显示从1开始
            //文字往下移 +textHeight/4
            canvas.drawText(String.format("%.1f", areaWidth) + "*" + String.format("%.1f", areaHeight) + "m",
                    tmpPoint[0], tmpPoint[1] + radius / 2 + textHeight / 4 + textHeight / 3, mTextPaint);
        } else {
            getTransformedPoint(mMapView.getTransform(), area.center.x, area.center.y);
            canvas.drawCircle(tmpPoint[0], tmpPoint[1], radius / 2 + 5, orderBgPaint);
            canvas.drawText((order + 1) + "", tmpPoint[0], tmpPoint[1] + textHeight / 3, mTextPaint);   //编号程序里从0开始 显示从1开始
        }

        canvas.rotate(-area.rotate, tmpPoint[0], tmpPoint[1]);
    }


    private void drawIcon1(Canvas canvas, float scale) {
        getTransformedPoint(mMapView.getTransform(), area.lt.x - deleteIcon.getWidth() / 2f / scale, area.lt.y - deleteIcon.getHeight() / 2f / scale);
        canvas.drawBitmap(deleteIcon, tmpPoint[0], tmpPoint[1], null);
        if ((((YXMapView) mMapView).canRotateCleanArea)) {
            getTransformedPoint(mMapView.getTransform(), area.rt.x - rotateIcon.getWidth() / 2f / scale, area.rt.y - rotateIcon.getHeight() / 2f / scale);
            canvas.drawBitmap(rotateIcon, tmpPoint[0], tmpPoint[1], null);
        }
        getTransformedPoint(mMapView.getTransform(), area.rb.x - scaleIcon.getWidth() / 2f / scale, area.rb.y - scaleIcon.getHeight() / 2f / scale);
        canvas.drawBitmap(scaleIcon, tmpPoint[0], tmpPoint[1], null);
    }


    @Override
    public boolean isEditable() {
        return isCleanAreaEditable;
    }


}
